#pragma once
#include <iostream>
#include <unordered_map>
#include <mutex>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include "log.hpp"

typedef websocketpp::server<websocketpp::config::asio> websocketServer;

class OnlineUser
{
private:
    std::unordered_map<uint32_t, websocketServer::connection_ptr> _user_hall_map;
    std::unordered_map<uint32_t, websocketServer::connection_ptr> _user_room_map;
    std::mutex _mutex; 
public:
    OnlineUser()
    { }
    ~OnlineUser()
    { }
    void addUserHall(uint32_t id, const websocketServer::connection_ptr& ptr)
    {
        Log(INFO, "User %d add userhall", id);
        std::unique_lock<std::mutex> lock(_mutex);
        _user_hall_map.insert(std::make_pair(id, ptr));
    }
    void addUserRoom(uint32_t id, const websocketServer::connection_ptr& ptr)
    {
        Log(INFO, "User %d add userroom", id);
        std::unique_lock<std::mutex> lock(_mutex);
        _user_room_map.insert(std::make_pair(id, ptr));
    }
    void deleteUserHall(uint32_t id)
    {
        Log(INFO, "User %d delete userhall", id);
        std::unique_lock<std::mutex> lock(_mutex);
        _user_hall_map.erase(id);
    }
    void deleteUserRoom(uint32_t id)
    {
        Log(INFO, "User %d delete userroom", id);
        std::unique_lock<std::mutex> lock(_mutex);
        _user_room_map.erase(id);
    }
    bool findInHall(uint32_t id)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto iter = _user_hall_map.find(id);
        if(iter == _user_hall_map.end())
        {
            Log(WARNING, "Can't Find in Hall");
            return false;
        }
        return true;
    }
    bool findInRoom(uint32_t id)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto iter = _user_room_map.find(id);
        if(iter == _user_room_map.end())
        {
            Log(WARNING, "Can't Find in Room");
            return false;
        }
        return true;
    }
    websocketServer::connection_ptr idToConnFromhall(uint32_t id)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto iter = _user_hall_map.find(id);
        if(iter == _user_hall_map.end())
        {
            Log(WARNING, "Can't Find in Hall");
            return websocketServer::connection_ptr();
        }
        return iter->second;
    }
    websocketServer::connection_ptr idToConnFromroom(uint32_t id)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        auto iter = _user_room_map.find(id);
        if(iter == _user_room_map.end())
        {
            Log(WARNING, "Can't Find in Room");
            return websocketServer::connection_ptr();
        }
        return iter->second;
    }    
};